// ChModSel.cpp : implementation file
//

#include "stdafx.h"
#include "VolDia.h"
#include "ChModSel.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CVolDiaApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CChModSel dialog


CChModSel::CChModSel(CWnd* pParent /*=NULL*/)
	: CDialog(CChModSel::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChModSel)
	m_Auto = -1;
	m_Prot = -1;
	m_Semia = -1;
	m_ManNoInt = -1;
	m_ManSingChan = -1;
	m_editMode = _T("");
	//}}AFX_DATA_INIT
	m_fromMimic = false;
	
	GetDynCurrentMode(&this->m_currentMode);
	switch(this->m_currentMode){
		case M_NO_MODE:
			this->m_editMode.Format(_T("No mode"));
			break;
		case M_AUTOMATIC:
			this->m_editMode.Format(_T("Automatic"));
			m_Auto = 0;
			break;
		case M_SEMIAUTO:
			this->m_editMode.Format(_T("Semi-Automatic"));
			m_Semia = 0;
			break;
		case M_PROTECT:
			this->m_editMode.Format(_T("Protected Manual"));
			m_Prot = 0;
			break;
		case M_MAN_WO_INT:
			this->m_editMode.Format(_T("Manual without Interlocks"));
			m_ManNoInt = 0;
			break;
		default:
			this->m_editMode.Format(_T("Unknown mode"));
			break;
	}
	
}


void CChModSel::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChModSel)
	DDX_Control(pDX, IDC_MAN_NO_INT, m_ManNoIntC);
	DDX_Control(pDX, IDC_MAN_SING_CH, m_ManSingChC);
	DDX_Control(pDX, IDC_PROT, m_ProtC);
	DDX_Control(pDX, IDC_SEMIA, m_SemiaC);
	DDX_Control(pDX, IDC_AUTO, m_AutoC);
	DDX_Control(pDX, IDCONFIRM, m_Conf);
	DDX_Control(pDX, IDC_CURR_MODE, m_CurrMode);
	DDX_Radio(pDX, IDC_AUTO, m_Auto);
	DDX_Radio(pDX, IDC_PROT, m_Prot);
	DDX_Radio(pDX, IDC_SEMIA, m_Semia);
	DDX_Radio(pDX, IDC_MAN_NO_INT, m_ManNoInt);
	DDX_Radio(pDX, IDC_MAN_SING_CH, m_ManSingChan);
	DDX_Text(pDX, IDC_CURR_MODE, m_editMode);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChModSel, CDialog)
	//{{AFX_MSG_MAP(CChModSel)
	ON_WM_CREATE()
	ON_BN_CLICKED(IDCONFIRM, OnConfirm)
	ON_BN_CLICKED(IDC_AUTO, OnAuto)
	ON_BN_CLICKED(IDC_SEMIA, OnSemia)
	ON_BN_CLICKED(IDC_PROT, OnProt)
	ON_EN_SETFOCUS(IDC_CURR_MODE, OnSetfocusCurrMode)
	ON_BN_CLICKED(IDC_MAN_SING_CH, OnManSingCh)
	ON_BN_CLICKED(IDC_MAN_NO_INT, OnManNoInt)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChModSel message handlers

int CChModSel::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	return 0;
}


BOOL CChModSel::OnInitDialog(){
	RETCOND			retCnd;
	TAGIDX			tagIdx;
	TAGVALEX		tagValChA, tagValChB;
	int				mode = 0;
	CString			temp;
/*
	RETSTAT			retSt;
	bool			movFlag;

	retSt = IsMovementInProgress(&movFlag);
	if(retSt != RT_NORMAL){
		MessageBox(_T("Error checking if any movement is in progress."), _T("Error"), MB_OK | MB_ICONERROR);
		CDialog::OnCancel();
	}

	if(movFlag){
		MessageBox(_T("A movement is currently in progress.\nOperating mode change is forbidden."), _T("Warning"), MB_OK | MB_ICONINFORMATION);
		CDialog::OnCancel();
	}
*/

	CDialog::OnInitDialog();

	ActivateControls();

	if(SingleChannelControlActive()){
		retCnd = GetTagIdx(TWN_BYPASS_A, &tagIdx);
		if(retCnd != R_NORMAL){
			MessageBox(_T("Error reading Real time Database."), _T("Error"), MB_OK);
			return FALSE;
		}
		retCnd = TagRead(&tagIdx, &tagValChA);
		if(retCnd != R_NORMAL){
			MessageBox(_T("Error reading Real time Database."), _T("Error"), MB_OK);
			return FALSE;
		}
		retCnd = GetTagIdx(TWN_BYPASS_B, &tagIdx);
		if(retCnd != R_NORMAL){
			MessageBox(_T("Error reading Real time Database."), _T("Error"), MB_OK);
			return FALSE;
		}
		retCnd = TagRead(&tagIdx, &tagValChB);
		if(retCnd != R_NORMAL){
			MessageBox(_T("Error reading Real time Database."), _T("Error"), MB_OK);
			return FALSE;
		}

		if((GtBit((short int)(tagValChA.value.val_di), 15) == 1) && (GtBit((short int)(tagValChB.value.val_di), 15) == 1)){
			MessageBox(_T("Both channels A and B are in failure."), _T("Error"), MB_OK);
			this->m_AutoC.EnableWindow(false);
			this->m_SemiaC.EnableWindow(false);
			this->m_ProtC.EnableWindow(false);
			this->m_ManNoIntC.EnableWindow(false);
			this->m_ManSingChC.EnableWindow(false);
			this->m_Conf.EnableWindow(false);
			return FALSE;
		}
		if((GtBit((short int)(tagValChA.value.val_di), 15) == 0) && (GtBit((short int)(tagValChB.value.val_di), 15) == 1)){
			m_CurrMode.SetWindowText(_T("Manual single Channel (A)"));
			this->m_AutoC.EnableWindow(false);
			this->m_SemiaC.EnableWindow(false);
			this->m_ProtC.EnableWindow(false);
			this->m_ManNoIntC.EnableWindow(false);
			this->m_ManSingChC.EnableWindow(false);
			this->m_Conf.EnableWindow(false);
			SetDynCurrentMode(M_MAN_SINGLE_CH);
			m_ManSingChan = 0;
		}
		if((GtBit((short int)(tagValChA.value.val_di), 15) == 1) && (GtBit((short int)(tagValChB.value.val_di), 15) == 0)){
			m_CurrMode.SetWindowText(_T("Manual single Channel (B)"));
			this->m_AutoC.EnableWindow(false);
			this->m_SemiaC.EnableWindow(false);
			this->m_ProtC.EnableWindow(false);
			this->m_ManNoIntC.EnableWindow(false);
			this->m_ManSingChC.EnableWindow(false);
			this->m_Conf.EnableWindow(false);
			SetDynCurrentMode(M_MAN_SINGLE_CH);
			m_ManSingChan = 0;
		}
	}
	if(((GtBit((short int)(tagValChA.value.val_di), 15) == 0) && (GtBit((short int)(tagValChB.value.val_di), 15) == 0)) || (SingleChannelControlActive())){
		GetDynCurrentMode(&this->m_currentMode);
		switch(this->m_currentMode){
			case M_NO_MODE:
				this->m_editMode.Format(_T("No mode"));
				break;
			case M_AUTOMATIC:
				this->m_editMode.Format(_T("Automatic"));
				m_Auto = 0;
				break;
			case M_SEMIAUTO:
				this->m_editMode.Format(_T("Semi-Automatic"));
				m_Semia = 0;
				break;
			case M_PROTECT:
				this->m_editMode.Format(_T("Protected Manual"));
				m_Prot = 0;
				break;
			case M_MAN_WO_INT:
				this->m_editMode.Format(_T("Manual without Interlocks"));
				m_ManNoInt = 0;
				break;
			default:
				this->m_editMode.Format(_T("Unknown mode"));
				break;
		}
	}
	UpdateData(false);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CChModSel::OnConfirm(){
	RETSTAT		retSt;
	bool		movFlag;
	int			risp;
	int			mode = 0;
	int			oldMode;
	int			local;
 	
	if(CheckUser())
		return;

	GetDynCurrentMode(&oldMode);

	retSt = IsMovementInProgress(&movFlag);
	if(retSt != RT_NORMAL){
		MessageBox(_T("Error checking if any movement is in progress."), _T("Error"), MB_OK | MB_ICONERROR);
		return;
	}

	if(movFlag){
		MessageBox(_T("A movement is currently in progress.\nOperating mode change is forbidden."), _T("Warning"), MB_OK | MB_ICONINFORMATION);
		return;
	}

	UpdateData(true);
	risp = MessageBox(_T("Confirm operational mode change?"), NULL, MB_YESNO | MB_ICONQUESTION);
	if(risp == IDYES){
		if((m_Auto != 0) && (m_Prot != 0) && (m_Semia != 0) && (m_ManNoInt != 0))
			MessageBox(_T("Insert a valid mode before confirm."));
		else{
			if(m_Auto == 0)
				mode = M_AUTOMATIC;
			else if(m_Prot == 0)
				mode = M_PROTECT;
			else if(m_Semia == 0)
				mode = M_SEMIAUTO;
			else if(m_ManNoInt == 0)
				mode = M_MAN_WO_INT;
			else if(m_ManSingChan == 0)
				mode = M_MAN_SINGLE_CH;
			else
				mode = M_NO_MODE;

			switch(oldMode){
			case M_AUTOMATIC:
			case M_SEMIAUTO:
				if((mode != M_AUTOMATIC) && (mode != M_SEMIAUTO)){
					
					if(theApp.m_pDlg->m_pElemMoveDialog != NULL){
						if(::IsWindow(theApp.m_pDlg->m_pElemMoveDialog->m_hWnd) != 0)
							theApp.m_pDlg->m_pElemMoveDialog->SendMessage(WM_CLOSE, 0, 0);
					}

					if(theApp.m_pDlg->m_pPhaseExecDialog != NULL){
						if(::IsWindow(theApp.m_pDlg->m_pPhaseExecDialog->m_hWnd) != 0)
							theApp.m_pDlg->m_pPhaseExecDialog->SendMessage(WM_CLOSE, 0, 0);
					}
					
				}
				ClearStationTCFlag();
				

				break;
			case M_PROTECT:
				
				if(theApp.m_pDlg->m_pManual != NULL){
					if(::IsWindow(theApp.m_pDlg->m_pManual->m_hWnd) != 0)
						theApp.m_pDlg->m_pManual->SendMessage(WM_CLOSE, 0, 0);
				}

				break;
			}

			theApp.m_pDlg->m_ignoreOpChange = true;

			SetDynCurrentMode(mode);
			this->m_currentMode = mode;
			GetDynCurrentMode(&mode);
			switch(mode){
			case M_NO_MODE:
				this->m_editMode.Format(_T("No mode"));
				break;
			case M_AUTOMATIC:
				this->m_editMode.Format(_T("Automatic"));
				break;
			case M_SEMIAUTO:
				this->m_editMode.Format(_T("Semi-Automatic"));
				break;
			case M_PROTECT:
				this->m_editMode.Format(_T("Protected Manual"));
				break;
			case M_MAN_SINGLE_CH:
				this->m_editMode.Format(_T("Manual single Channel"));
				break;
			case M_MAN_WO_INT:
				this->m_editMode.Format(_T("Manual without Interlocks"));
				break;
			default:
				this->m_editMode.Format(_T("Unknown mode"));
				break;
			}
			UpdateData(false);
		}
		if(!m_fromMimic){
			theApp.m_pDlg->m_pPhaseExecDialog->EchoStrAdd(_T("Operating mode successfully selected."));
		}
		//Se sono in manuale abilito il controllo di sicurezza e disabilito il cambio di pagina automatico.//
		if(((mode == M_PROTECT) || (mode == M_MAN_WO_INT))){ 
			//if(theApp.m_pDlg->m_SafeChecks == false)
			//	theApp.m_pDlg->ActivateSafeChecks();
			if(theApp.m_pDlg->m_ManBeeper == false)
				theApp.m_pDlg->ActivateManBeeper();
		}
		else if((mode != M_PROTECT) && (mode != M_MAN_WO_INT)){ 
			//if(theApp.m_pDlg->m_SafeChecks == true)
			//	theApp.m_pDlg->DeactivateSafeChecks();
			if(theApp.m_pDlg->m_ManBeeper == true)
				theApp.m_pDlg->DeactivateManBeeper();
		}	

		if((mode == M_AUTOMATIC) || (mode == M_SEMIAUTO)){
			if(theApp.m_pDlg->m_pPhaseExecDialog == NULL){
				theApp.m_pDlg->m_pPhaseExecDialog = new CPhaseExec;
				theApp.m_pDlg->m_pPhaseExecDialog->Create(IDD_PHASE_EXEC, NULL);
				theApp.m_pDlg->m_pPhaseExecDialog->ShowWindow(SW_SHOW);
			}
			else
				theApp.m_pDlg->m_pPhaseExecDialog->ShowWindow(SW_RESTORE);

			InitAutoFlags();

			//retSt = GetStationID(&local);
			//SetMasterStation(local);
		}	
		else if(mode == M_PROTECT){
			if(theApp.m_pDlg->m_pManual != NULL){
				theApp.m_pDlg->m_pManual->DestroyWindow();
				theApp.m_pDlg->m_pManual = NULL;
				theApp.m_pDlg->m_pManual = new ManualMode;
				theApp.m_pDlg->m_pManual->Create(IDD_MANUAL, NULL);
				theApp.m_pDlg->m_pManual->ShowWindow(SW_SHOW);

			}
			else{
				theApp.m_pDlg->m_pManual = new ManualMode;
				theApp.m_pDlg->m_pManual->Create(IDD_MANUAL, NULL);
				theApp.m_pDlg->m_pManual->ShowWindow(SW_SHOW);
			}
			InitManualFlags();
			retSt = GetStationID(&local);
			SetMasterStation(local);
		}else{
			InitManualFlags();
			retSt = GetStationID(&local);
			SetMasterStation(local);
		}

		this->ShowWindow(SW_HIDE);
	}
}

void CChModSel::OnAuto() 
{
	if(CheckUser())
		return;

	m_Auto = 0;
	m_Prot = -1;
	m_Semia = -1;
	m_ManNoInt = -1;
	m_ManSingChan = -1;
	UpdateData(false);
}

void CChModSel::OnSemia() 
{
	if(CheckUser())
		return;

	m_Auto = -1;
	m_Prot = -1;
	m_Semia = 0;
	m_ManNoInt = -1;
	m_ManSingChan = -1;
	UpdateData(false);	
}

void CChModSel::OnProt() 
{
	if(CheckUser())
		return;

	m_Auto = -1;
	m_Prot = 0;
	m_Semia = -1;
	m_ManNoInt = -1;
	m_ManSingChan = -1;
	UpdateData(false);	
}


void CChModSel::OnSetfocusCurrMode() 
{
	if(CheckUser())
		return;

	SetFocus();
}

void CChModSel::OnManSingCh() 
{
	if(CheckUser())
		return;

	m_Auto = -1;
	m_Prot = -1;
	m_Semia = -1;
	m_ManNoInt = -1;
	m_ManSingChan = 0;
	UpdateData(false);	
}

void CChModSel::OnManNoInt() 
{
	if(CheckUser())
		return;

	m_Auto = -1;
	m_Prot = -1;
	m_Semia = -1;
	m_ManNoInt = 0;
	m_ManSingChan = -1;
	UpdateData(false);	
}

void CChModSel::OnCancel(){
	CDialog::OnCancel();
}

void CChModSel::ActivateControls(){
	RETSTAT		retSt;
	
	//Controllo l'utente//
	retSt = GetLoggedUserLevel(theApp.m_pDlg->m_opStation, &this->m_loggedUser);
	if(retSt != RT_NORMAL){
		MessageBox(_T("Unknown logged user."), _T("Error"), MB_OK);
		return;
	}
	switch(this->m_loggedUser){
	case SYSMGR:
	case LEVEL1:
	case LEVEL2:
		this->m_AutoC.EnableWindow(true);
		this->m_SemiaC.EnableWindow(true);
		this->m_ProtC.EnableWindow(true);
		this->m_ManNoIntC.EnableWindow(true);
		this->m_ManSingChC.EnableWindow(false);
		this->m_Conf.EnableWindow(true);
		break;
	case LEVEL3:
	case LEVEL4:
		this->m_AutoC.EnableWindow(true);
		this->m_SemiaC.EnableWindow(true);
		this->m_ProtC.EnableWindow(true);
		this->m_ManNoIntC.EnableWindow(false);
		this->m_ManSingChC.EnableWindow(false);
		this->m_Conf.EnableWindow(true);
		break;
	case LEVEL5:
		this->m_AutoC.EnableWindow(false);
		this->m_SemiaC.EnableWindow(false);
		this->m_ProtC.EnableWindow(false);
		this->m_ManNoIntC.EnableWindow(false);
		this->m_ManSingChC.EnableWindow(false);
		this->m_Conf.EnableWindow(false);
		break;
	}
}

bool CChModSel::CheckUser(){
	RETSTAT		retSt;
	int			currentUser;
	
	currentUser = this->m_loggedUser;
	//Controllo l'utente//
	retSt = GetLoggedUserLevel(theApp.m_pDlg->m_opStation, &this->m_loggedUser);
	if(retSt != RT_NORMAL){
		MessageBox(_T("Unknown logged user."), _T("Error"), MB_OK);
		return false;
	}
	if(m_loggedUser != currentUser){
		ActivateControls();
		return true;
	}
	return false;
}

bool CChModSel::SingleChannelControlActive(){
	LONG	res;
	HKEY	hKey;
	DWORD	dwBufLen = 0;
	DWORD	active;
    
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
				 TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Volgodonsk\\Voldia"),
				 0,
				 KEY_QUERY_VALUE,
				 &hKey);
	dwBufLen = sizeof(active);
	res = RegQueryValueEx(hKey,
						  TEXT("SingleChannelControlActive"),
						  NULL,
						  NULL,
						  (LPBYTE)&active,
						  &dwBufLen);
	if(res == ERROR_SUCCESS){
		if((DWORD)active == 0)
			return false;
		else
			return true;
	}

	return false;
}

void CChModSel::OpMonitorChange(int mode){
	
	switch(mode){
		case M_NO_MODE:
			this->m_editMode.Format(_T("No mode"));
			m_Auto = -1;
			m_Prot = -1;
			m_Semia = -1;
			m_ManNoInt = -1;
			m_ManSingChan = -1;
			break;
		case M_AUTOMATIC:
			this->m_editMode.Format(_T("Automatic"));
			m_Auto = 0;
			m_Prot = -1;
			m_Semia = -1;
			m_ManNoInt = -1;
			m_ManSingChan = -1;
			break;
		case M_SEMIAUTO:
			this->m_editMode.Format(_T("Semi-Automatic"));
			m_Auto = -1;
			m_Prot = -1;
			m_Semia = 0;
			m_ManNoInt = -1;
			m_ManSingChan = -1;
			break;
		case M_PROTECT:
			this->m_editMode.Format(_T("Protected Manual"));
			m_Auto = -1;
			m_Prot = 0;
			m_Semia = -1;
			m_ManNoInt = -1;
			m_ManSingChan = -1;
			break;
		case M_MAN_SINGLE_CH:
			this->m_editMode.Format(_T("Manual single Channel"));
			m_Auto = -1;
			m_Prot = -1;
			m_Semia = -1;
			m_ManNoInt = -1;
			m_ManSingChan = 0;
			break;
		case M_MAN_WO_INT:
			this->m_editMode.Format(_T("Manual without Interlocks"));
			m_Auto = -1;
			m_Prot = -1;
			m_Semia = -1;
			m_ManNoInt = 0;
			m_ManSingChan = -1;
			break;
		default:
			this->m_editMode.Format(_T("Unknown mode"));
			m_Auto = -1;
			m_Prot = -1;
			m_Semia = -1;
			m_ManNoInt = -1;
			m_ManSingChan = -1;
			break;
	}
		
	UpdateData(false);
		
	//Se sono in manuale abilito il controllo di sicurezza e disabilito il cambio di pagina automatico.//
	if((mode == M_PROTECT) || (mode == M_MAN_WO_INT)){ 
		//if(theApp.m_pDlg->m_SafeChecks == false)
		//	theApp.m_pDlg->ActivateSafeChecks();
		if(theApp.m_pDlg->m_ManBeeper == false)
			theApp.m_pDlg->ActivateManBeeper();
	}
	else if((mode != M_PROTECT) && (mode != M_MAN_WO_INT)){ 
		//if(theApp.m_pDlg->m_SafeChecks == true)
		//	theApp.m_pDlg->DeactivateSafeChecks();
		if(theApp.m_pDlg->m_ManBeeper == true)
			theApp.m_pDlg->DeactivateManBeeper();
	}

	if(mode != M_PROTECT){
		if(theApp.m_pDlg->m_pManual != NULL){
			if(::IsWindow(theApp.m_pDlg->m_pManual->m_hWnd) != 0)
				theApp.m_pDlg->m_pManual->SendMessage(WM_CLOSE, 0, 0);
		}
	}
	else if((mode != M_AUTOMATIC) && (mode != M_SEMIAUTO)){
		if(theApp.m_pDlg->m_pElemMoveDialog != NULL){
			if(::IsWindow(theApp.m_pDlg->m_pElemMoveDialog->m_hWnd) != 0)
				theApp.m_pDlg->m_pElemMoveDialog->SendMessage(WM_CLOSE, 0, 0);
		}
		if(theApp.m_pDlg->m_pPhaseExecDialog != NULL){
			if(::IsWindow(theApp.m_pDlg->m_pPhaseExecDialog->m_hWnd) != 0)
				theApp.m_pDlg->m_pPhaseExecDialog->SendMessage(WM_CLOSE, 0, 0);
		}
	}
}